package cn.lnexin.file;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GZipUtil {
	
	public static final int BUFFER = 4096;
	public static final String EXT = ".gz";
	
	/**
	 * 数据压缩
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] compress(byte[] data) throws Exception {
		ByteArrayInputStream bais = new ByteArrayInputStream(data);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		// 压缩
		compress(bais, baos);
		
		byte[] output = baos.toByteArray();
		
		baos.flush();
		baos.close();
		
		bais.close();
		
		return output;
	}
	
	/**
	 * 文件压缩
	 * 
	 * @param file
	 * @throws Exception
	 */
	public static void compress(File file) throws Exception {
		compress(file, true);
	}
	
	/**
	 * 文件压缩
	 * 
	 * @param file
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static void compress(File file, boolean delete) throws Exception {
		FileInputStream fis = new FileInputStream(file);
		FileOutputStream fos = new FileOutputStream(file.getPath() + EXT);
		
		compress(fis, fos);
		
		fis.close();
		fos.flush();
		fos.close();
		
		if (delete) {
			file.delete();
		}
	}
	
	/**
	 * 数据压缩
	 * 
	 * @param is
	 * @param os
	 * @throws Exception
	 */
	public static void compress(InputStream is, OutputStream os) throws Exception {
		
		GZIPOutputStream gos = new GZIPOutputStream(os);
		
		int count;
		byte data[] = new byte[BUFFER];
		while ((count = is.read(data, 0, BUFFER)) != -1) {
			gos.write(data, 0, count);
		}
		
		gos.finish();
		
		gos.flush();
		gos.close();
	}
	
	/**
	 * 文件压缩
	 * 
	 * @param path
	 * @throws Exception
	 */
	public static void compress(String path) throws Exception {
		compress(path, true);
	}
	
	/**
	 * 文件压缩
	 * 
	 * @param path
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static void compress(String path, boolean delete) throws Exception {
		File file = new File(path);
		compress(file, delete);
	}
	
	/**
	 * 数据解压缩
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] decompress(byte[] data) throws Exception {
		ByteArrayInputStream bais = new ByteArrayInputStream(data);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		// 解压缩
		
		decompress(bais, baos);
		
		data = baos.toByteArray();
		
		baos.flush();
		baos.close();
		
		bais.close();
		
		return data;
	}
	
	/**
	 * 文件解压缩
	 * 
	 * @param file
	 * @throws Exception
	 */
	public static String decompress(File file) throws Exception {
		return decompress(file, true);
	}
	
	/**
	 * 文件解压缩
	 * 
	 * @param file
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static String decompress(File file, boolean delete) throws Exception {
		FileInputStream fis = new FileInputStream(file);
		String outfn = file.getPath().replace(EXT, "");
		FileOutputStream fos = new FileOutputStream(outfn);
		decompress(fis, fos);
		fis.close();
		fos.flush();
		fos.close();
		
		if (delete) {
			file.delete();
		}
		return outfn;
	}
	
	public static void decompress(File file, String newFN, boolean delete) throws Exception {
		FileInputStream fis = new FileInputStream(file);
		FileOutputStream fos = new FileOutputStream(newFN);
		decompress(fis, fos);
		fis.close();
		fos.flush();
		fos.close();
		
		if (delete) {
			file.delete();
		}
	}
	
	/**
	 * 数据解压缩
	 * 
	 * @param is
	 * @param os
	 * @throws Exception
	 */
	public static void decompress(InputStream is, OutputStream os) throws Exception {
		
		GZIPInputStream gis = new GZIPInputStream(is);
		
		int count;
		byte data[] = new byte[BUFFER];
		while ((count = gis.read(data, 0, BUFFER)) != -1) {
			os.write(data, 0, count);
		}
		
		gis.close();
	}
	
	/**
	 * 文件解压缩
	 * 
	 * @param path
	 * @throws Exception
	 */
	public static String decompress(String path) throws Exception {
		return decompress(path, true);
	}
	
	/**
	 * 文件解压缩
	 * 
	 * @param path
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static String decompress(String path, boolean delete) throws Exception {
		File file = new File(path);
		return decompress(file, delete);
	}
	
}
